home *** CD-ROM | disk | FTP | other *** search
/ User's Choice Windows CD / User's Choice Windows CD (CMS Software)(1993).iso / utility3 / wtj008.zip / NOTBAD.ZIP / NOTBAD.CPP < prev    next >
C/C++ Source or Header  |  1992-06-15  |  16KB  |  538 lines

  1. // notbad.cpp RHS 1/15/92
  2.  
  3. #include<stdio.h>
  4. #include<memory.h>
  5. #include<time.h>
  6. #include<string.h>
  7. #include<fcntl.h>
  8. #include<sys\stat.h>
  9. #include<io.h>
  10. #include<ctype.h>
  11. #include"stdwin.h"
  12. #include"editwin.h"
  13. #include"openfile.h"
  14. #include"notbad.h"
  15.  
  16. char *szAppName = "NotBad";
  17. char *szUntitled = "(untitled)";
  18. HWND editWinHdl = NULL;
  19. char findbuffer[50];
  20. BOOL upperonly = FALSE;
  21. BOOL forward = TRUE;
  22.  
  23. BOOL CALLBACK AboutDlg(HWND hDlg, UINT message, WPARAM wParam, LPARAM)
  24.     {
  25.     switch(message)
  26.         {
  27.         case WM_INITDIALOG:
  28.             SetDlgItemInt(hDlg,4,GetWindowTextLength(editWinHdl),FALSE);
  29.             return TRUE;
  30.  
  31.         case WM_COMMAND:
  32.             if (wParam == IDOK || wParam == IDCANCEL)
  33.                 {
  34.                 EndDialog(hDlg, TRUE);
  35.                 return TRUE;
  36.                 }
  37.             break;
  38.         }
  39.     return FALSE;
  40.     }
  41.  
  42. BOOL CALLBACK FindDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM)
  43.     {
  44.     BOOL result;
  45.  
  46.     switch(message)
  47.         {
  48.         case WM_INITDIALOG:                        // message: initialize    
  49.             SetDlgItemText(hDlg,IDM_FINDSPEC,findbuffer);
  50.             CheckDlgButton(hDlg,IDM_CASEBUTTON,upperonly);
  51.             CheckRadioButton(hDlg,IDM_FORBUTTON,IDM_BACKBUTTON,
  52.                 (forward ? IDM_FORBUTTON : IDM_BACKBUTTON));
  53.             SetFocus(GetDlgItem(hDlg, IDM_FINDSPEC));
  54.             return FALSE; // Indicates the focus is set to a control
  55.  
  56.         case WM_COMMAND:
  57.             switch(wParam)
  58.                 {
  59.                 case IDM_CASEBUTTON:
  60.                     CheckDlgButton(hDlg,IDM_CASEBUTTON,
  61.                         !IsDlgButtonChecked(hDlg,IDM_CASEBUTTON));
  62.                     upperonly = !upperonly;
  63.                     return TRUE;
  64.                 case IDM_FORBUTTON:
  65.                 case IDM_BACKBUTTON:
  66.                     CheckRadioButton(hDlg,IDM_FORBUTTON,IDM_BACKBUTTON,
  67.                         (!IsDlgButtonChecked(hDlg,IDM_FORBUTTON) ? 
  68.                             IDM_FORBUTTON : IDM_BACKBUTTON));
  69.                     forward = !forward;
  70.                     return TRUE;
  71.                 case IDC_CANCEL:
  72.                     EndDialog(hDlg, FALSE);
  73.                     return TRUE;
  74.                 case IDOK:
  75.                     if(GetDlgItemText(hDlg,IDM_FINDSPEC,findbuffer,
  76.                         sizeof(findbuffer)-1))
  77.                         EndDialog(hDlg,TRUE);
  78.                     else
  79.                         MessageBox(hDlg,"Nothing to find!",NULL, 
  80.                             MB_OK | MB_ICONHAND);
  81.                     return TRUE;
  82.                 }
  83.         }
  84.     return FALSE;
  85.     }
  86.  
  87.     // searches for 'str' from 'buf[len]' to buf
  88. char *findrstr(char *buf, char *str, int len, int upperonly)
  89.     {
  90.     int buflen = strlen(buf);
  91.     int slen = strlen(str);
  92.     if(len < buflen)
  93.         buflen = len;
  94.  
  95.     int i, j;
  96.     if(upperonly)
  97.         for( buflen--, slen-- ; buflen >= slen; buflen--)
  98.             {
  99.             if(buf[buflen] == str[slen])
  100.                 {
  101.                 for(i = slen-1, j = buflen-1; i >= 0; i--, j--)
  102.                     if(buf[j] != str[i])
  103.                         break;
  104.                 if(i < 0)
  105.                     return &buf[j+1];
  106.                 }
  107.             }
  108.     else
  109.         for( buflen--, slen-- ; buflen >= slen; buflen--)
  110.             {
  111.             if(toupper(buf[buflen]) == toupper(str[slen]))
  112.                 {
  113.                 for(i = slen-1, j = buflen-1; i >= 0; i--, j--)
  114.                     if(toupper(buf[j]) != toupper(str[i]))
  115.                         break;
  116.                 if(i < 0)
  117.                     return &buf[j+1];
  118.                 }
  119.             }
  120.  
  121.     return NULL;
  122.     }
  123.  
  124. void GetDateTime(char *buf)
  125.     {
  126.     char *days[7] = 
  127.         { 
  128.         "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
  129.         "Friday", "Saturday" 
  130.         };
  131.     char *months[12] = 
  132.         {
  133.         "January", "February", "March", "April", "May", "June",
  134.         "July", "August", "September", "October", "November", "December"
  135.         };
  136.     int year,month,day,dow;
  137.     int hour, minutes, seconds;
  138.  
  139.     _AH = 0x2A;
  140.     asm int 0x21;
  141.  
  142.     dow = _AL;
  143.     year = _CX;
  144.     month = _DH;
  145.     day = _DL;
  146.  
  147.     _AH = 0x2C;
  148.     asm int 0x21;
  149.     hour = _CH;
  150.     minutes = _CL;
  151.     seconds = _DH;
  152.  
  153.     BOOL pm = FALSE;
  154.  
  155.     if(hour > 12)
  156.         {
  157.         pm = TRUE;
  158.         hour -= 12;
  159.         }
  160.     if(!hour)
  161.         hour = 12;
  162.     sprintf(buf,"%s, %s %d, %04d, %d:%02d:%02d%s",
  163.         days[dow],months[month],day,year,hour,minutes,seconds,
  164.         (pm ? "pm" : "am"));
  165.     }
  166.  
  167. class myApp : public WinAppStdWindow
  168.     {
  169.     EditWin *editWin;
  170.     HMENU myMenu;
  171.     BOOL menusOff;
  172.     BOOL wordWrap;
  173.     int scrollMin, scrollMax;
  174.     char filename[80];
  175.     char newfile[80];
  176.     char appName[10];
  177.     HCURSOR hHourGlass;
  178.     BOOL fileSaved;
  179.  
  180. public:
  181.     myApp(char *name) : WinAppStdWindow(name)
  182.         {
  183.         editWin = NULL;
  184.         myMenu = NULL;
  185.         SetClassMenu("MENU_1");
  186.         SetClassIcon("ICON_1");
  187.         menusOff = TRUE;
  188.         wordWrap = FALSE;
  189.         strcpy(filename,szUntitled);
  190.         strcpy(appName,szAppName);
  191.         hHourGlass = LoadCursor(NULL,IDC_WAIT);
  192.         *findbuffer = '\0';
  193.         }
  194.     void SetTitle(void)
  195.         {
  196.         if(!hWnd)
  197.             return;
  198.         char buf[100];
  199.         sprintf(buf,"%s - %s",appName,filename);
  200.         SetWindowText(hWnd,buf);
  201.         }
  202.     void CheckForChanges(void)
  203.         {
  204.         if(editWin->EMGETMODIFY())
  205.             {
  206.             char buf[50];
  207.             sprintf(buf,"Save changes to %s?",strupr(filename));
  208.             if(MessageBox(hWnd,buf,appName,MB_YESNO) == IDYES)
  209.                 SendMessage(hWnd,WM_COMMAND,IDM_SAVE,0L);
  210.             }
  211.         }
  212.     void InitEditWindow(RECT *rect = NULL)
  213.         {
  214.         editWin = new EditWin(hWnd,IDM_CNTRL);
  215.         if(!wordWrap)
  216.             {
  217.             editWin->AddHScroll();
  218.             editWin->SetAutoHScroll();
  219.             }
  220.         if(rect)
  221.             {
  222.             editWin->SetWinX(0);
  223.             editWin->SetWinY(0);
  224.             editWin->SetWinWidth(rect->right-rect->left);
  225.             editWin->SetWinHeight(rect->bottom-rect->top);
  226.             }
  227.         editWin->AddVScroll();
  228.         editWin->SetAutoVScroll();
  229.         editWin->AddBorder();
  230.         editWin->SetLeftText();
  231.         editWin->SetMultiLine();
  232.         editWin->Create();
  233.         editWinHdl = editWin->GetHandle();
  234.         }
  235.  
  236.     void WMCREATE(void)
  237.         {
  238.         InitEditWindow();
  239.         myMenu = GetMenu(hWnd);
  240.         lstrcpy(newfile,GetCmdLine());
  241.         if(*newfile)
  242.             SendMessage(hWnd,WM_COMMAND,IDM_OPENARG,0L);
  243.         SetTitle();
  244.         }
  245.         
  246.     void WMSETFOCUS(void)
  247.         {
  248.         if(editWin)
  249.             SetFocus(editWin->GetHandle());
  250.         }
  251.     void WMSIZE(void)
  252.         {
  253.         if(editWin)
  254.             MoveWindow(editWin->GetHandle(),0,0,LOWORD(lParam)-0,
  255.                 HIWORD(lParam)-0,TRUE);
  256.         }
  257.     void WMINITMENU(void)
  258.         {
  259.         EnableMenuItem(myMenu,IDM_PASTE,
  260.             IsClipboardFormatAvailable(CF_TEXT) ?
  261.                 (MF_BYCOMMAND | MF_ENABLED)     :
  262.                 (MF_BYCOMMAND | MF_GRAYED));
  263.  
  264.         LONG l = editWin->EMGETSEL();
  265.         WORD diff = HIWORD(l)-LOWORD(l);
  266.         EnableMenuItem(myMenu,IDM_CUT,
  267.             diff ? (MF_BYCOMMAND | MF_ENABLED) : (MF_BYCOMMAND | MF_GRAYED));
  268.         EnableMenuItem(myMenu,IDM_COPY,
  269.             diff ? (MF_BYCOMMAND | MF_ENABLED) : (MF_BYCOMMAND | MF_GRAYED));
  270.         EnableMenuItem(myMenu,IDM_DEL,
  271.             diff ? (MF_BYCOMMAND | MF_ENABLED) : (MF_BYCOMMAND | MF_GRAYED));
  272.         EnableMenuItem(myMenu,IDM_UNDO,
  273.             editWin->EMCANUNDO() ? 
  274.                 (MF_BYCOMMAND | MF_ENABLED) : 
  275.                 (MF_BYCOMMAND | MF_GRAYED));
  276.         }
  277.     void WMDESTROY(void)    {   PostQuitMessage(0);     }
  278.     void WMQUERYENDSESSION(void)
  279.         {
  280.         CheckForChanges();
  281.         MsgReturnValue = -1;
  282.         }
  283.  
  284.     void WMCLOSE(void)      
  285.         {   
  286.         CheckForChanges();
  287.         DestroyWindow(hWnd);    
  288.         }
  289.     void WMCOMMAND(void);
  290.     };
  291.  
  292.  
  293. void myApp::WMCOMMAND(void)
  294.     {
  295.     switch(wParam)
  296.         {
  297.         case IDM_CNTRL:
  298.             {
  299.             switch(HIWORD(lParam))
  300.                 {
  301.                 case EN_CHANGE:
  302.                     if(menusOff)
  303.                         {
  304.                         EnableMenuItem(myMenu,IDM_SELECTALL,
  305.                             MF_BYCOMMAND | MF_ENABLED);
  306.                         menusOff = FALSE;
  307.                         }
  308.                     break;
  309.                 case EN_ERRSPACE:
  310.                     MessageBox(hWnd,"Cannot insert any more characters..."
  311.                         "out of memory!",appName,MB_OK);
  312.                     break;
  313.                 }
  314.             }
  315.             break;
  316.         case IDM_UNDO:
  317.             editWin->EMUNDO();
  318.             break;
  319.         case IDM_PASTE:
  320.             editWin->WMPASTE();
  321.             break;
  322.         case IDM_COPY:
  323.             editWin->WMCOPY();
  324.             break;
  325.         case IDM_CUT:
  326.             editWin->WMCUT();
  327.             break;
  328.         case IDM_DEL:
  329.             editWin->WMCLEAR();
  330.             break;
  331.         case IDM_EXIT:
  332.             WMCLOSE();
  333.             break;
  334.         case IDM_TIMEDATE:
  335.             {
  336.             char buf[50];
  337.             GetDateTime(buf);
  338.             buf[strlen(buf)] = '\0';
  339.             editWin->EMREPLACESEL(buf);
  340.             }
  341.             break;
  342.         case IDM_SELECTALL:
  343.             editWin->EMSETSEL(MAKELONG(0,
  344.                 GetWindowTextLength(editWin->GetHandle())));
  345.             break;
  346.         case IDM_ABOUT:
  347.             DialogBox(GetInstance(), "ABOUTBOX", hWnd, ::AboutDlg);
  348.             break;
  349.         case IDM_NEW:
  350.             CheckForChanges();
  351.             strcpy(filename,szUntitled);
  352.             SetTitle();
  353.             SetWindowText(editWin->GetHandle(),"");
  354.             break;
  355.             
  356.         case IDM_OPEN:
  357.             {
  358.             CheckForChanges();
  359.             OpenFileDlg Ofile;
  360.             Ofile.Init(".txt","*.txt",IDC_EDIT,IDC_LISTBOX,
  361.                 IDC_PATH,OPENFILE_FILEOPEN);
  362.             Ofile.SetCaption("Open File");
  363.             Ofile.SetButtonText("Open");
  364.             if(DialogBox(GetInstance(), "FILEOPEN", hWnd, 
  365.                     OpenFileDlg::DlgProc))
  366.                 strcpy(newfile,Ofile.GetFileName());
  367.             else
  368.                 break;
  369.             }
  370.             // fall thru
  371.         case IDM_OPENARG:
  372.             {
  373.             int fh = open(newfile,O_RDONLY);
  374.             if(fh == -1)
  375.                 {
  376.                 MessageBox(hWnd,"Unable to open file.",appName,MB_OK);
  377.                 break;
  378.                 }
  379.             long len;
  380.             if((len = filelength(fh)) > 32767L)
  381.                 {
  382.                 MessageBox(hWnd,"File too big for NOTBAD buffer.",appName,
  383.                     MB_OK);
  384.                 close(fh);
  385.                 break;
  386.                 }
  387.             WORD bytesread;
  388.             HANDLE hdl = GlobalAlloc(GMEM_MOVEABLE,len+1);
  389.             LPSTR lp = (LPSTR)GlobalLock(hdl);
  390.             if(!hdl || !lp)
  391.                 {
  392.                 MessageBox(hWnd,"Unable to allocate read-buffer for file.",
  393.                     appName, MB_OK);
  394.                 if(hdl)
  395.                     GlobalFree(hdl);
  396.                 break;
  397.                 }
  398.             strcpy(filename,newfile);
  399.             _lread(fh,lp,(WORD)len);           
  400.             close(fh);
  401.             lp[len] = '\0';
  402.             SetTitle();
  403.             SetWindowText(editWin->GetHandle(),lp);
  404.             GlobalUnlock(hdl);
  405.             GlobalFree(hdl);
  406.             }
  407.             break;
  408.  
  409.         case IDM_FIND:
  410.             if(!DialogBox(GetInstance(), "FIND", hWnd, FindDlgProc))
  411.                 break;
  412.             // fall thru
  413.         case IDM_FINDNEXT:
  414.             {
  415.             char *p = (char  *)LocalLock(editWin->EMGETHANDLE());
  416.             char *bufstart = p;
  417.             int len = strlen(findbuffer);
  418.             int offset = ((wParam == IDM_FINDNEXT) && forward) ? 
  419.                 HIWORD(editWin->EMGETSEL()) :
  420.                 LOWORD(editWin->EMGETSEL());
  421.             char *q = NULL;
  422.             if(forward)
  423.                 {
  424.                 if(upperonly)
  425.                     q = strstr(&p[offset],findbuffer);
  426.                 else
  427.                     {
  428.                     int i;
  429.                     p = &p[offset];
  430.                     for(i = 0; i < strlen(p); i++)
  431.                         if(!strncmpi(findbuffer,&p[i],len))
  432.                             {
  433.                             q = &p[i];
  434.                             break;
  435.                             }
  436.                     }
  437.                 }
  438.             else
  439.                 q = findrstr(p,findbuffer, offset,
  440.                     (upperonly ? TRUE : FALSE));
  441.             if(!q)
  442.                 MessageBox(hWnd,"Not found!",appName,MB_OK);
  443.             else
  444.                 editWin->EMSETSEL(MAKELONG(q-bufstart,q+len-bufstart));
  445.             
  446.             LocalUnlock(editWin->EMGETHANDLE());
  447.             }
  448.             break;
  449.                 
  450.         case IDM_SAVEAS:
  451.             {
  452.             char *p = strchr(filename,'.');
  453.             OpenFileDlg Ofile;
  454.             char buf[7];
  455.             if(p)
  456.                 {
  457.                 strcpy(buf,"*");
  458.                 strcat(buf,p);
  459.                 }
  460.             else
  461.                 strcpy(buf,"*.*");
  462.             Ofile.Init(buf,filename,IDC_EDIT,IDC_LISTBOX,IDC_PATH,
  463.                 OPENFILE_FILESAVE);
  464.             Ofile.SetCaption("Save As");
  465.             Ofile.SetButtonText("Save File");
  466.             if(DialogBox(GetInstance(), "FILEOPEN", 
  467.                 hWnd, OpenFileDlg::DlgProc))
  468.                 {
  469.                 char temp[80];
  470.                 strcpy(temp,filename);
  471.                 strcpy(filename,Ofile.GetFileName());
  472.                 SendMessage(hWnd,WM_COMMAND,IDM_SAVE,0L);
  473.                 if(editWin->EMGETMODIFY())
  474.                     strcpy(filename,temp);
  475.                 else
  476.                     SetTitle();
  477.                 }
  478.             }
  479.             break;
  480.         case IDM_SAVE:
  481.             if(!strcmp(filename,szUntitled))
  482.                 {
  483.                 SendMessage(hWnd,WM_COMMAND,IDM_SAVEAS,0L);
  484.                 break;
  485.                 }
  486.                 
  487.             HCURSOR old = SetCursor(hHourGlass);
  488.             {
  489.             int fh = open(filename,O_WRONLY | O_CREAT | O_TRUNC | O_BINARY);
  490.             if(fh == -1)
  491.                 {
  492.                 MessageBox(hWnd,"Unable to open file for writing.",
  493.                     appName,MB_OK);
  494.                 break;
  495.                 }
  496.             editWin->EMFMTLINES(0);
  497.             HANDLE hdl = editWin->EMGETHANDLE();
  498.             char *p = (char *)LocalLock(hdl);
  499.             unsigned len = strlen(p);
  500.             write(fh,p,len);
  501.             close(fh);
  502.             LocalUnlock(hdl);
  503.             editWin->EMCLEARMODIFY();
  504.             }
  505.             SetCursor(old);
  506.             break;
  507.             
  508.         case IDM_WORDWRAP:
  509.             {
  510.             RECT rect;
  511.             GetWindowRect(editWin->GetHandle(),&rect);
  512.             EditWin *oldEditWin = editWin;
  513.             HANDLE oldHdl = oldEditWin->EMGETHANDLE();
  514.  
  515.             wordWrap = !wordWrap;
  516.  
  517.             ShowWindow(oldEditWin->GetHandle(),SW_HIDE);
  518.             InitEditWindow(&rect);
  519.             HANDLE newHdl = editWin->EMGETHANDLE();
  520.             editWin->EMSETHANDLE(oldHdl);
  521.             oldEditWin->EMSETHANDLE(newHdl);
  522.             delete oldEditWin;
  523.  
  524.             CheckMenuItem(myMenu,IDM_WORDWRAP, wordWrap ? 
  525.                     (MF_BYCOMMAND | MF_CHECKED) : 
  526.                     (MF_BYCOMMAND | MF_UNCHECKED));
  527.             }
  528.             break;
  529.         }
  530.     }
  531.  
  532. int PASCAL WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
  533.     {
  534.     myApp MyWin(szAppName);
  535.     MyWin.Display();                    // open the window
  536.     return MyWin.Run();                 // process any messages
  537.     }
  538.